__author__ =  "Paul Reiners"

import string
import getopt
import sys
import gdata.spreadsheet.service
import my_auth

class Uploader():
    """
    Deletes old contents of a Google Worksheet and adds new contents from a .csv
    file.
    """

    def __init__(self, email=None, password=None):
        "Initialize attributes of an Uploader."
        if not email:
            email = raw_input('Spreadsheets API | Text DB Tests\n'
                                 'Please enter your username(email): ')
        if not password:
            password = getpass.getpass()
        self.gd_client = gdata.spreadsheet.service.SpreadsheetsService()
        self.gd_client.email = email
        self.gd_client.password = password
        #self.gd_client.source = 'Upload Batting Stats'
        self.gd_client.ProgrammaticLogin()
        self.curr_key = ''
        self.curr_wksht_id = ''
        self.list_feed = None
        #self.infile = infile
    
    def _PromptForSpreadsheet(self):
        # Get the list of spreadsheets
        feed = self.gd_client.GetSpreadsheetsFeed()
        self._PrintFeed(feed)
        input = raw_input('\nSelection: ')
        id_parts = feed.entry[string.atoi(input)].id.text.split('/')
        self.curr_key = id_parts[len(id_parts) - 1]
      
    def _PromptForWorksheet(self):
        # Get the list of worksheets
        feed = self.gd_client.GetWorksheetsFeed(self.curr_key)
        self._PrintFeed(feed)
        input = raw_input('\nSelection: ')
        id_parts = feed.entry[string.atoi(input)].id.text.split('/')
        self.curr_wksht_id = id_parts[len(id_parts) - 1]
      
    def _PrintFeed(self, feed):
        for i, entry in enumerate(feed.entry):
            if isinstance(feed, gdata.spreadsheet.SpreadsheetsCellsFeed):
                print '%s %s\n' % (entry.title.text, entry.content.text)
            elif isinstance(feed, gdata.spreadsheet.SpreadsheetsListFeed):
                print '%s %s %s\n' % (i, entry.title.text, entry.content.text)
            else:
                print '%s %s\n' % (i, entry.title.text)
    
    def prompt_delete_old_rows_and_add_new_rows(self):
        """
        Delete old rows and add new ones, but prompt user for spreadsheet and 
        worksheet IDs if they're not already set.
        """
        if not self.curr_key:
            self._PromptForSpreadsheet()
        if not self.curr_wksht_id:
            self._PromptForWorksheet()

        self._delete_and_add_rows()

    def _delete_and_add_rows(self):
        """
        First, delete all the rows (except the header row) in the spreadsheet 
        and then call method to add rows.
        """
        cells_feed = self.gd_client.GetCellsFeed(self.curr_key, self.curr_wksht_id)
        row_count = int(cells_feed.row_count.text)
        while (row_count > 1):
            self._list_delete_action(0)
            cells_feed = self.gd_client.GetCellsFeed(self.curr_key, self.curr_wksht_id)
            row_count = int(cells_feed.row_count.text)
      
        self._fill_in_rows()
  
    def _list_delete_action(self, index):
        "Delete the row with the given index."
        self.list_feed = self.gd_client.GetListFeed(self.curr_key, self.curr_wksht_id)
        self.gd_client.DeleteRow(self.list_feed.entry[index])
        print 'Deleted!'
  
    def _fill_in_rows(self):
        "Create new rows with the new data."
        infile = open(self.infile)
        header_line = infile.readline().strip()
        headers = header_line.split(',')
        col_count = len(headers)
        while infile:
            line = infile.readline().strip()
            if len(line) > 0:
                row_data = {}
                parts = line.split(',')
                for col in range(col_count):
                    row_data[headers[col].lower()] = parts[col].strip()
                try:
                    self._list_insert_action(row_data)
                except (gdata.service.RequestError, SyntaxError):
                    print 'Error inserting row:', row_data
                    print 'Will skip that row.'
            else:
                break;
    
    def _list_insert_action(self, row_data):
        "Insert a new row with data."
        entry = self.gd_client.InsertRow(row_data,
            self.curr_key, self.curr_wksht_id)
        if isinstance(entry, gdata.spreadsheet.SpreadsheetsList):
            print 'Inserted!'
    
    def set_spreadsheet(self, spreadsheet):
        "Set the spreadsheet we're using by its ID."
        self.curr_key = spreadsheet
      
    def set_worksheet(self, worksheet):
        "Set the worksheet (a page of a spreadsheet) we're using by its ID."
        self.curr_wksht_id = worksheet
    
    def _run(self):
        "Fill in a blank worksheet."
        self._PromptForSpreadsheet()
        self._PromptForWorksheet()
        self._fill_in_rows()

def main():
  usage = 'python gdata_uploader.py --user [username] --pw [password]'
  # parse command line options
  try:
    opts, args = getopt.getopt(sys.argv[1:], "", ["user=", "pw="])
  except getopt.error, msg:
    print usage
    sys.exit(2)
  
  user = ''
  pw = ''
  key = ''
  # Process options
  for o, a in opts:
    if o == "--user":
      user = a
    elif o == "--pw":
      pw = a

  if user == '' or pw == '' or len(args) < 1:
    print usage
    sys.exit(2)
    
  infile = args[0]
        
  uploader = Uploader(user, pw, infile)
  uploader._run()

if __name__ == '__main__':
  main()
